/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2002, GeoVISTA Center
 * Licensed under Simplified BSD License
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
*
* Out-of-dated
* @Original Author: jin Chen
* @date: Jan 3, 2005$
* @version: 1.0
*/
package edu.psu.geovista.app.visualclassifier.classify.v2.gui;

import edu.psu.geovista.app.visualclassifier.classify.v2.DefaultESVisualClassifier;
import edu.psu.geovista.app.visualclassifier.classify.v2.ESVisualClassifier;
import edu.psu.geovista.app.visualclassifier.classify.v2.LgToolTip;
import edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.DynamicSwatchPane;
import edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl;
import edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v2.FixedSwatchPaneImpl;
import edu.psu.geovista.classification.*;
import edu.psu.geovista.classification.setting.ClassifySetting;
import edu.psu.geovista.ui.event.ClassificationResultEvent;
import edu.psu.geovista.ui.event.ClassificationResultListener;
import epoviz.trex.common.swing.components.jpanel.MouseEventProcessPanel;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.HashMap;

public class LegendControl1 extends MouseEventProcessPanel
        implements ClassificationResultListener {


    public static final int DFX = 50;
    public static final int DFY = 50;
    public static final int LX=200;
    public static final int LY=250;
    //GUI
    DynamicSwatchPane swp;  // 
    protected MyMouseInputAdapter msl;
    protected boolean normalsize= true;//;
    private JLabel xlb=new JLabel();
    private JLabel ylb=new JLabel();
    private JPanel labelP=new JPanel();  //display variables' name
    private LgToolTip tooltip=new LgToolTip();
    //classification
    ESVisualClassifier vc;
    ClassificationResultItf classifyResult;
    HashMap colorCategories=new HashMap();
    //Color[][] colors;
    /**
     *
     * @param colors    
     */
    public LegendControl1(Color[][] colors) {
        //this.colors=colors;
        //swatchPanes
        swp=new MouseEventPassingSwatchPane(colors);//edu.psu.geovista.app.pcp.toolkits.colorpalette.v1.DynamicSwatchPaneImpl(colors);
        swp.setGap(1,1);
        swp.setSwatchBorderColor(Color.white );

        // 
        // 
        ((JPanel)swp).setToolTipText("");

        this.setSize(new Dimension(DFX,DFY));
        this.setLayout(new BorderLayout());
        msl = new MyMouseInputAdapter() ;

        this.setSwatchPaneMouseListener(swp,msl);

        //label panel
        labelP.setLayout(new GridLayout(2,1));
        labelP.add(xlb);
        labelP.add(ylb);


        this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED) );// .createLineBorder(Color.BLACK ) );
        this.add((JPanel)swp);
        // new ContaineeDragger(this);



    }
    /*******************************************************************************************************
     *                services
     *******************************************************************************************************/
    public void doClassification(ClassifySetting settings){
          if(vc!=null)
         ((DefaultESVisualClassifier)vc).classifyOnLegendControl(settings);
    }

    public void setColors(Color[] colors){
        this.swp.setColors(colors);
        //this.setSwatchPaneMouseListener(swp,msl); //since swatches are newly created, need attach mouselistener again
    }
    public void setColors(Color[][] colors){
        this.swp.setColors(colors);
        //this.setSwatchPaneMouseListener(swp,msl); //since swatches are newly created, need attach mouselistener again
    }


    public void setXvarname(String s) {
        if(s!=null&&!s.trim().equals("") )
            s="X: "+s;
        setLabel(this.xlb ,s);
    }

    public void setYvarname(String s) {
        /*if(yvarname!=null&&!yvarname.trim().equals("") )
        this.ylb.setText("Y:"+yvarname);
        else{
        ylb.setText("");
        }*/
        if(s!=null&&!s.trim().equals("") )
            s="Y: "+s;

        setLabel(this.ylb ,s);
    }

    private void setLabel(JLabel lb, String s){
        if(s==null||s.trim().equals("") ){
            lb.setText("");
        }
        else{
            lb.setText(s);
        }
        lb.setFont(new java.awt.Font("Arial", 1, 14));

    }

    public void setVisualClassifier(ESVisualClassifier vc) {
        this.vc = vc;
    }


    /*******************************************************************************************************
     *                event
     *******************************************************************************************************/
    private void setSwatchPaneMouseListener(DynamicSwatchPane swp,MouseInputAdapter msl){
        JPanel p=(JPanel) swp;
        p.removeMouseListener(msl); //prevent duplication
        p.addMouseListener(msl);

        p.removeMouseMotionListener((MouseMotionListener)msl); //prevent duplication
        p.addMouseMotionListener((MouseMotionListener)msl);

    }

    public void classificationResultChanged(ClassificationResultEvent e) {
        ClassificationResultItf cr = (ClassificationResultItf) e.getClassificationResult();
        mapColorsCategories(cr);

        this.repaint();

    }


    /*******************************************************************************************************
     *                Function
     *******************************************************************************************************/

    /***********************************************************************************
     *         Color and classification map
     ************************************************************************************/
    /**
     * Legend has classification and swatch has only color
     * Assume each category has a unique color, we can
     * set up a map between color and category
     * @param cr
     */
    private void mapColorsCategories(ClassificationResultItf cr) {
        int colcount = cr.getNumberOfClassX(); //num of category in x direction , it is actually # of column in a legend
        int rowcount = cr.getNumberOfClassY();//num of category in y direction , it is actually # of row in a legend
        this.colorCategories.clear();

        if(colcount>0&&rowcount>0){//2 dimension
            Color[][] colors=new Color[rowcount][colcount];

            for (int i=rowcount-1;i>=0;i--){
                for (int j=0;j<colcount;j++){
                    Category2D ctg = cr.getCategory(j,i);
                    if(ctg!=null&&ctg.getVisualInfo()!=null){
                        VisualInfo vf = ctg.getVisualInfo();
                           Color color = vf.getColor();
                           colors[i][j]=color;
                               this.colorCategories.put(color, ctg);
                    }
                    else{
                        //todo null category or color exception
                    }
                }
            }//for
            this.swp.setColors(colors);
            /* this is for enlarged LegendControl, for now, we not use  enlarged LegendControl
            String attX = cr.getAttX();
            String attY = cr.getAttY();
            this.setXvarname(attX);
            this.setYvarname(attY);*/

        }//if
        else if(colcount>0){//1 dimension
            Color[] colors=new Color[colcount];
            for (int i=0;i<colcount;i++){

                CategoryItf category = cr.getCategory(i);
                if(category!=null&&category.getVisualInfo()!=null){
                    Color color = category.getVisualInfo().getColor();
                    colors[i]=color;
                    this.colorCategories.put(color, category);
                }
            }//for
            this.swp.setColors(colors);
           /* String attX = cr.getAttX();
            this.setXvarname(attX);
            this.setYvarname("");*/
        }//else
    }


    /*******************************************************************************************************
     *                support
     *******************************************************************************************************/
    private void performClickOnSwatchPane ( MouseEvent e){
        int id = e.getID();
        if(id==MouseEvent.MOUSE_CLICKED){
            int clickCount = e.getClickCount();
            if(clickCount==2){
                //System.out.println("double clicked");
                if(vc!=null)
                    vc.showup();
                //System.out.println("click 2");
                //resetSize();
            }
            else  if(clickCount==1){
                if(vc!=null){
                    //vc.showup();
                }
                //resetSize();
                //System.out.println("click 1");
            }

        }
    }
    private void performMouseMoveOnSwatchPane(MouseEvent e) {
        DynamicSwatchPaneImpl swatchp = ((DynamicSwatchPaneImpl)swp);
        DynamicSwatchPaneImpl.Swatch swatch = swatchp.getSwatchByLocation(e.getX() ,e.getY());
        if (swatch!=null){
            Color color = swatch.getColor();
            Object obj = this.colorCategories.get(color);
            CategoryItf ctg = (CategoryItf) obj;
            if(ctg!=null){
                //String tooltip = this.getTooltip(ctg);
                Point colorIndex = swatch.getIndex();
                Color[] rowColors = swatchp.getRowColors(colorIndex.x );
                Color[] columnColors = swatchp.getColumnColors(colorIndex.y );
                this.tooltip.setTooltip(rowColors,columnColors,ctg);
                tooltip.repaint();
               // ((JPanel)swp).setToolTipText(tooltip);
            }
            else{//todo temp for test, need remove later
                //((JPanel)swp).setToolTipText("set tool tip");
                Color[] dSampleColors = edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v2.DynamicSwatchPaneImpl.create1DSampleColors();
                Category2D ctg2d=new Basic2DCategory(null,null,"",null,null);
                ctg2d.setXVariableName("X Variable");
                ctg2d.setXRange(new Range(1000000,1000));
                ctg2d.setYVariableName("Y Variable");
                ctg2d.setYRange(new Range(8000000,6000));

                this.tooltip.setTooltip(dSampleColors,dSampleColors,ctg2d);

            }
        }
    }

    private String getTooltip(CategoryItf ctg){
        String s="";
        String xs="X variable:";

        if(ctg instanceof Category2D){//2D category
            String ys="Y variable:";
            Category2D ctg2d = ((Category2D)ctg);

            Range xr = ctg2d.getXRange();
            Range yr = ctg2d.getYRange();
            xs=xs+xr.toString()+"\n" ;
            ys=ys+yr.toString() +"\n" ;
            s=xs+ys;
        }
        else{//1 dimension category
            Range xr = ctg.getRange();
            xs=xs+xr.toString()+"\n" ;
            s=xs;
        }
        return s;

    }
    private void resetSize(){
        if(normalsize){
            this.setSize(new Dimension(LX,LY));
            this.add(this.labelP ,BorderLayout.SOUTH);
            normalsize=false;//true;
        }
        else{
            this.setSize(new Dimension(DFX,DFY));
            this.remove(labelP);
            normalsize=true;//true;
        }
        this.revalidate();
        this.repaint();
        JComponent parent = (JComponent) this.getParent();
        Component[] cps = parent.getComponents();
        parent.revalidate();
        parent.repaint();
    }

    class MyMouseInputAdapter extends MouseInputAdapter {
        public void mouseClicked(MouseEvent e){
            performClickOnSwatchPane(e);
        }
        public void mouseMoved(MouseEvent e) {
            performMouseMoveOnSwatchPane(e);
        }
        public void mouseDragged(MouseEvent e) {}

    }
    /************************************************************************************
     *               
     ************************************************************************************/
    class MouseEventPassingSwatchPane extends DynamicSwatchPaneImpl{
        public MouseEventPassingSwatchPane(Color[][] colors) {
            super(colors);
            this.enableEvents(AWTEvent.MOUSE_EVENT_MASK );
            this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
        }

        protected void processMouseEvent(MouseEvent e) {
            super.processMouseEvent(e );
            MouseEventProcessPanel p=(MouseEventProcessPanel) LegendControl1.this;
            p.processMouseEvent(e);
        }
        protected void processMouseMotionEvent(MouseEvent e) {
            super.processMouseMotionEvent(e);
            MouseEventProcessPanel p=(MouseEventProcessPanel) LegendControl1.this;
            p.processMouseMotionEvent(e);
            //System.out.println("processMouseMotionEvent");
        }
      /**
       *  
       * @return
       */
         public JToolTip createToolTip() {
            tooltip.setComponent(this);
            System.out.println("create customized tooltip");
            return tooltip;
        }
    }

    /*******************************************************************************************************
     *                test
     *******************************************************************************************************/

    public  static Color[][] getSampleColors(){
        int[][] colorValues=new int[][]{
            {255, 255, 255, // first row.
             192, 192, 192,
             255, 0, 0,
             255, 255, 0,
             0, 255, 0,
             0, 255, 255,
             0, 0, 255,
             255, 0, 255},
            {0, 0, 0,  // second row.
             128, 128, 128,
             128, 0, 0,
             128, 128, 0,
             0, 128, 0,
             0, 128, 128,
             0, 0, 128,
             128, 0, 128,},
            {255, 199, 199,  // 3rd row.
             83, 109, 165,
             204,  255,204,
             153, 153, 204,
             204, 204, 214,
             0, 180, 110,
             252, 253, 205,
             212, 133, 213}
        };
        Color[][] mycolors= FixedSwatchPaneImpl.convert2RowBased(colorValues);
        //SwatchPanel sp=new SwatchPanel(30,30,colorValues);
        return mycolors;
    }
   


}

